package com.skyline.feed.dao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.skyline.common.mongo.MongoTemplate;
import com.skyline.feed.dao.SubscribedFeedDao;
import com.skyline.feed.type.FeedType;

@Repository("subscribedFeedDao")
public class SubscribedFeedDaoImpl implements SubscribedFeedDao {

	@Autowired
	private MongoTemplate mongoTemplate;

	private List<DBCollection> collections = new ArrayList<DBCollection>();

	@Value("${feed.subscribedFeed.maxFeedLevel}")
	private Integer MAX_FEED_LEVEL;

	@Value("${feed.column.time}")
	private String TIME;

	@Value("${feed.column.resourceId}")
	private String RESOURCE_ID;

	@Value("${feed.column.resourceId.Title}")
	private String TITLE;

	@Value("${feed.column.content}")
	private String CONTENT;

	@Value("${feed.column.providerId}")
	private String PROVIDER_ID;

	@Value("${feed.column.providerNickname}")
	private String PROVIDER_NICKNAME;

	@Value("${feed.column.providerPortrait}")
	private String PROVIDER_PORTRAIT;

	@Value("${feed.column.ownerId}")
	private String OWNER_ID;

	@Value("${feed.column.type}")
	private String TYPE;

	@Value("${feed.pagination.pageSize}")
	private Integer PAGE_SIZE;

	@Value("${feed.subscribedFeed.collectionsPrefix}")
	private String subscribedFeedCollectionsPrefix;

	private boolean initaled = false;

	private void inital() {
		if (initaled == false || collections.size() == 0) {
			try {
				for (int i = 0; i <= MAX_FEED_LEVEL; i++) {
					DBCollection collection = mongoTemplate.getCollection(subscribedFeedCollectionsPrefix + i);
					collections.add(i, collection);
				}
				initaled = true;
			} catch (Exception e) {
				collections.clear();
				e.printStackTrace();
			}
		}
	}

	@Override
	public void insertFeed(Long resourceId, String title, String content, Long providerId, String providerNickname,
			String providerPortrait, Long ownerId, FeedType type, Integer level) {
		this.inital();
		BasicDBObject feed = new BasicDBObject();
		feed.put(TIME, (new Date()).getTime());
		feed.put(RESOURCE_ID, resourceId);
		feed.put(TITLE, title);
		feed.put(CONTENT, content);
		feed.put(PROVIDER_ID, providerId);
		feed.put(PROVIDER_NICKNAME, providerNickname);
		feed.put(PROVIDER_PORTRAIT, providerPortrait);
		feed.put(OWNER_ID, ownerId);
		feed.put(TYPE, type.toString());
		this.insertFeed(feed);

	}

	@Override
	public void insertFeeds(DBCursor cursor, Long ownerId) {
		this.inital();
		while (cursor.hasNext()) {
			DBObject feed = cursor.next();
			feed.put(OWNER_ID, ownerId);
			// collections.get(0).insert(feed);
			this.insertFeed(feed);
		}

	}

	@Override
	public void insertFeeds(List<DBObject> feeds, Long ownerId) {
		this.inital();
		for (int i = 0; i < feeds.size(); i++) {
			feeds.get(i).put(OWNER_ID, ownerId);
		}
		collections.get(0).insert(feeds);
	}

	@Override
	public void insertFeed(DBObject obj) {
		this.inital();
		collections.get(0).insert(obj);
	}

	@Override
	public List<DBObject> queryFeeds(Long ownerId, Integer current, Integer level) {
		this.inital();
		return this.queryFeeds(ownerId, current, current + PAGE_SIZE, level);
	}

	@Override
	public DBObject queryNewestFeed(Long ownerId, Integer level) {
		this.inital();
		BasicDBObject condition = new BasicDBObject();
		condition.put(OWNER_ID, ownerId);
		BasicDBObject orderBy = new BasicDBObject();
		orderBy.put(TIME, -1);
		DBCursor cursor = collections.get(level).find(condition).limit(1).sort(orderBy);
		List<DBObject> feed = cursor.toArray();
		if (feed != null && feed.size() > 0) {
			return feed.get(0);
		} else {
			return null;
		}
	}

	@Override
	public List<DBObject> queryFeeds(Long ownerId, Integer start, Integer end, Integer level) {
		this.inital();
		BasicDBObject condition = new BasicDBObject();
		condition.put(OWNER_ID, ownerId);
		BasicDBObject orderBy = new BasicDBObject();
		orderBy.put(TIME, -1);
		DBCursor cursor = collections.get(level).find(condition).skip(start).limit(end - start).sort(orderBy);
		return cursor.toArray();
	}

}
